﻿using Microsoft.Extensions.Configuration;
using Nxg.Blog.Core.Extensions;
using System.Linq;
using System.Reflection;

namespace Nxg.Blog.Web.Features
{
    public class ConfigProvider : IConfigProvider
    {
        private readonly IConfiguration _config;

        public ConfigProvider(IConfiguration config)
        {
            _config = config;
        }

        public string this[string key]
        {
            get
            {
                return _config.GetSection(key).Value.ToString();
            }
        }

        public string this[string sectionName, string key]
        {
            get
            {
                return _config.GetSection($"{sectionName}:{key}").Value.ToString();
            }
        }

        public string GetAppSetting(string propertyName)
        {
            return _config.GetSection($"AppSettings:{propertyName}").Value.ToString();
        }

        public T GetAppSetting<T>(string propertyName) where T : struct
        {
            return _config.GetSection($"AppSettings:{propertyName}").Value.CastTo<T>();
        }

        public T GetSection<T>() where T : class, new()
        {
            return GetSection<T>(typeof(T).GetTypeInfo().Name);
        }

        public T GetSection<T>(string sectionName) where T : class, new()
        {
            var type = typeof(T);
            var instance = new T();
            instance.GetType().GetTypeInfo().GetProperties().ToList()
                .ForEach(x =>
                {
                    x.SetValue(instance, this[sectionName, x.Name].CastTo(x.PropertyType));
                });
            return instance;
        }
    }

    public interface IConfigProvider
    {
        string GetAppSetting(string propertyName);

        T GetSection<T>(string sectionName) where T : class, new();

        T GetSection<T>() where T : class, new();

        T GetAppSetting<T>(string propertyName) where T : struct;

        string this[string key] { get; }

        string this[string sectionName, string key] { get; }
    }
}
